/**
 *
 * @author baron
 *
 */
const enum SOCKETSTATE {
    login = 0,
    hall = 1
}
class SocketManager {
    public constructor() {
    }
    private _connectState: number = 0;

    private static _me: SocketManager;
    public static get me() {
        if (SocketManager._me == null)
            SocketManager._me = new SocketManager();
        return SocketManager._me;
    }
    private webSocket: egret.WebSocket;
    public sid: string;
    //    private getClazz(protoRes: string,protoName: string): any {
    //        var proto: string = RES.getRes(protoRes);               //加载PB数据结果定义字符
    //        console.log(proto);//
    //        var builder: any = dcodeIO.ProtoBuf.loadProto(proto);          //解析PB数据定义文件，生成PB对象构造器 (loadProtoFile用这个可以代替RES的功能，自己选）
    //        var clazz: any = builder.build(protoName);                     //构建一个PB数据结构（messageName为PB中定义的结果名）
    //        var data: any = new clazz();
    //        return data;
    //    }
    //封包类型
    private packetClass: any;
    public startSend(msg: any): any {
        if (!this.webSocket) {
            return;
        }
        if (this.webSocket.connected == false) {
            this.startReconnect();
            return;
        }
        console.log("发送：" + msg);
        this.packetClass = GameMain.me.proto.msgclass("head.NetMsg");
        var packet: any = new this.packetClass();
        var arraybuffer: ArrayBuffer = msg.encode().toArrayBuffer();
        packet.set("content", arraybuffer);

        packet.set("cmd", this.getCmdEnum(msg.__fullname));
        var arraybuffer2: ArrayBuffer = packet.encode().toArrayBuffer();

        var msgdata: egret.ByteArray = new egret.ByteArray(arraybuffer2);
        this.webSocket.writeBytes(msgdata);
        console.log("发送消息：", msg);
    }
    public reConect(_server: string, _port: number) {
        if (this.webSocket != null) {
            this.webSocket.removeEventListener(egret.ProgressEvent.SOCKET_DATA, this.onReceiveMessage, this);
            this.webSocket.removeEventListener(egret.Event.CONNECT, this.onSocketOpen, this);
            this.webSocket.removeEventListener(egret.Event.CLOSE, this.onSocketClose, this);
            this.webSocket.addEventListener(egret.IOErrorEvent.IO_ERROR, this.onSocketError, this)

            this.webSocket.close();

        }
        this.webSocket = new egret.WebSocket();
        this.webSocket.type = egret.WebSocket.TYPE_BINARY;
        this.webSocket.addEventListener(egret.ProgressEvent.SOCKET_DATA, this.onReceiveMessage, this);
        this.webSocket.addEventListener(egret.Event.CONNECT, this.onSocketOpen, this);
        this.webSocket.addEventListener(egret.Event.CLOSE, this.onSocketClose, this);
        this.webSocket.addEventListener(egret.IOErrorEvent.IO_ERROR, this.onSocketError, this);
        //this.webSocket.connect("119.29.201.42", 14341);
        this.webSocket.connect(_server, _port);

        GameMain.me.commonEvent.dispatchEvent(new egret.Event("loginserver", false, false));

        console.log("请求连接" + _server + "_" + _port);
        Global.showWaritPanel();

        egret.clearInterval(this.interId);
        this.interId = egret.setInterval(this.removeCode, this, 1000);
    }
    private removeCode() {
        if (this.codeArry.length > 0) {
            this.codeArry.pop();
        }
    }
    private codeArry: string[] = [];

    private recvBuf: egret.ByteArray = new egret.ByteArray();

    private onReceiveMessage(e: egret.Event): void {
        this.recvBuf.clear();
        this.recvBuf.endian = egret.Endian.LITTLE_ENDIAN;
        this.webSocket.readBytes(this.recvBuf);
        // console.log("收到数据", this.recvBuf.length);
        // var utfs = this.recvBuf.readUTFBytes(this.recvBuf.length);
        var cls = GameMain.me.proto.msgclass("head.NetMsg");
        var msgDataLen = this.recvBuf.length - this.recvBuf.position;
        var msgData = new egret.ByteArray();
        msgData.writeBytes(this.recvBuf, 0, msgDataLen);
        var msg = cls.decode(msgData.buffer);

        var cotentcls = GameMain.me.proto.getClsByCmd(msg.cmd);
        var data = cotentcls.decode(msg.content);
        var event = new NetEvent(msg.cmd.toString(), data);
        console.log('收到一个消息', msg.cmd, data);
        if (msg.error_code != null && msg.error_code != 0) {
            this.dealErrorCode(msg, event);//msg.error_code);
        } else {
            GameMain.me.evNet.dispatchEvent(event);
        }
    }
    private onSocketOpen(): void {
        console.log("连接成功");
        Global.hideWaritPanel();
        return;
        //if(DEBUG){}
        egret.clearInterval(this.interId);
        this.interId = egret.setInterval(this.requestHeartReq, this, this.intervalDuration);
    }
    public dealErrorCode(msg: any, evt: NetEvent) {
        var cls = GameMain.me.proto.msgclass("head.ErrorCode");
        for (var key in cls) {
            if (cls[key] == msg.error_code) {
                EffectUtils.showTips(msg.error_code + ":" + key, 1);
            }
        }
    }
    public getCmdEnum(fullname: string): number {
        var arr: string[] = fullname.split('.');
        var protofilename = arr[0];
        var codename = arr[1];
        var cmdclass: any = GameMain.me.proto.msgclass(protofilename + ".Cmd");
        var cmd1 = cmdclass["CMD_" + codename];
        return cmd1;
    }

    private intervalDuration: number = 10000; // duration between intervals, in milliseconds
    /**
     * 请求心跳包
     */
    public requestHeartReq(obj: any) {
        egret.clearTimeout(this.outId);
        this.outId = egret.setTimeout(this.checkHeart, this, 5000);
    }
    private outId: number;
    private interId: number;



    private heartBackBool: Boolean;
    private checkHeart(): void {
        if (this.heartBackBool == false) {
            EffectUtils.showTips("你已掉线，正在重连", 1);
            this.resetAll();
            this.startReconnect();
        }
    }
    private resetAll() {

    }
    private onSocketClose(): void {
        console.log("Socket Close");
        Global.showWaritPanel();

    }

    private onSocketError(event: egret.IOErrorEvent): void {
        console.log("----------------------------------------------------------------------------socket.error" + event.data);

        this.startReconnect();
    }
    private startReconnect() {
        GameMain.me.commonEvent.dispatchEvent(new egret.Event("reconnect", false, false));
    }






}
